ZahlInteger math Library

The imath library provides one string imath.version. We can see its value with the command
print (imath.version)
or equivalently with
local version in imath
print (version)
It also provides a number of functions, itemized below. Zahl has two types of numbers, which we may think of as small and big. Small numbers are stored in four bytes, whereas big numbers are stored as arrays of many bytes. Small number literals are indicated by decimals or hexadecimals preceded by 0x in the usual way. Big numbers, however, have no such literal expression for input. Instead they must created by the function imath.$, either from a string or a small number.
big = $ (small) or big = $ (string, [base])
For example, denoting output with a comment in the traditional way,
local $ in imath
print ($ (0xa)) --> 10
print ($ "9999999999999999999999") --> 9999999999999999999999
print ($ ("100", 2)) --> 4
The variables $0, ... ,$9 are initialized to the big numbers 0, ... ,9 respectively, for convenience. Note that
print ($5 == 5, type (5), type ($5)) --> false, int32, integer
but
local compare in imath
print (compare ($5, 5)) --> 0
The compare function produces the small numbers 1, 0, -1 as result according to whether the first argument is greater, equal or less than the second, whichever kind of numbers are used as arguments. Note that
print (2^31)   -->  -2147483648
because small numbers wrap around with modulus 2^32 but
print ($2^31)  -->  2147483648
because big numbers do not.
print ($2^($2^10))  -->
179769313486231590772930519078902473361797697894230657273430081157732675805500
963132708477322407536021120113879871393357658789768814416622492847430639474124
377767893424865485276302219601246094119453082952085005768838150682342462881473
913110540827237163350510684586298239947245938479716304835356329624224137216

Note that if a function, say f, in the imath library has for its first argument, x, a big number then

       imath.f (x, ... )
can also be expressed as
       x:f (...)
This is part of Lua's metamagic. So we could have used
$5:compare (5)
for the expression above.

The standard operators of arithmetic

        + - * / % ^
can be used with either kind of number, but the bitwise operators
        | & ~
can only be used with small numbers. However, the shift operators
       <<  >>
can be used if the left operand is big. The right operand must be small.

The function imath.tostring converts big numbers to strings and the function imath.tonumber converts big numbers to small, or gives an error if not possible, thus being a sort of inverse to imath.$.

Another pair of functions imath.text and imath.totext convert from/to nonempty strings to/from big numbers. These functions are useful in cryptography.

The function imath.root takes a big number for its first argument and a small, say n for its second. It returns the least big number not less than the n-th root of the first argument.

The function imath.bits returns as a small number the number of bits in the binary expression for its big number argument.

The function imath.quotrem returns two big number values, the quotient and remainder from its two big number arguments, the dividend and the divisor.

The function imath.egcd returns three big number arguments

             h, a, b = imath.egcd (x, y)
where h is the least big number such that
             h == a*x + b*y
In other words it is the greatest common divisor imath.gcd (x,y).

The function imath.powmod takes three big numbers, the base, the exponent and the modulus, as arguments and returns a big number. So

           imath.powmod (x, y, k)
has the value
           (x^y)%k
but only involves calculations with numbers less than k and so is to be preferred.

The remaining functions do just what you might expect. And in any case you can always experiment by using !Zahl.

Note that long doublequoted strings can be split up by using the escape sequence \z.

    local x = "aaaaaaaaaaaaaaaa\z
         bbbbbbbbbb"
    print (x) -->  aaaaaaaaaaaaaaaabbbbbbbbbb